home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 9 code / Tracks / Tracks_dcmd / TracksDCMD.c
Encoding:
C/C++ Source or Header  |  1992-11-16  |  8.2 KB  |  309 lines  |  [TEXT/MPS ]

  1. /**********************************************************************
  2.  
  3. Copyright 1990,1991 Orion Network Systems, Inc.
  4. All Rights reserved.
  5.  
  6. File:  TracksDCMD.c
  7. Author:  Brad Lowe
  8.  
  9. Tracks Debugger Command tool...  Allows you to do rudimentary Tracks 
  10. functions from the debugger.  This should only be used if your machine 
  11. crashes, and you have data in the circular buffer you want sent to a file.  
  12. Of couse there is no gaurentee that the Tracks driver is not trashed, and if 
  13. it is, the debugger will lockup..  Use this when you are sure there 
  14. is no more information to be gained from poking around in the debugger.  
  15.  
  16. Commands supported are: 
  17.     On:  Turns tracing on.  You must specify the target driver (the one
  18.     you are tracing, by doing a Tracks On .TestDrvr or whatever.
  19.     
  20.     ** The buffer must be initialized through the cdev before this call will work!
  21.     
  22.     Off:  Turns tracing off.
  23.     Write:  Writes whatever is in the buffer to your prefrence file.
  24.     Info:  Displays some info about Tracks.
  25.     
  26.     Remember that the cdev must be initialized once before you can use this...
  27.     It can be started from startup or from the cdev...
  28.     
  29. Building:
  30.  
  31.    The following MPW commands will build the dcmd and copy it to the
  32.    "Debugger Prefs" file in the System folder. The dcmd's name in
  33.    MacsBug will be the name of the file built by the Linker.
  34.    
  35.    ** This file must be in a folder within the Tracks source code folder.
  36.  
  37.     Note:  Be sure to link dcmdGlue.a.o first.  The files in the
  38.     dcmd libraries folder should come with Macsbugs
  39.  
  40.     C TracksDCMD.c
  41.     Link "{dcmdLib}"dcmdGlue.a.o TracksDCMD.c.o "{dcmdLib}"put.c.o ∂
  42.     "{dcmdLib}"DRuntime.o "{Libraries}"Interface.o -o Tracks
  43.     
  44.     # This will build the dcmd and copy it to your debugger prefs file or tmon file
  45.     BuildDcmd Tracks 1322
  46.     
  47.     Echo 'include "Tracks";'    |    Rez -a -o "{systemFolder}TMON Folder:dcmd holder"
  48.     Echo 'include "Tracks";'    |    Rez -a -o "{systemFolder}Debugger prefs"
  49.     
  50. **********************************************************************/
  51.  
  52. #include <Types.h>
  53. #include "dcmd.h"
  54. #include <Devices.h>
  55. #include <string.h>
  56. #include <Errors.h>
  57.  
  58. #include "::Tracks.h"        // Look one folder back for this file
  59. #include "Put.h"
  60.  
  61. void PutSignedWord(short err);
  62. Boolean EqlStr(const char *a, const char *b);
  63. short       GetDrvrRefNum(char *driverName);
  64.  
  65. pascal void CommandEntry (dcmdBlock* paramPtr)
  66. {
  67. Ptr     csParamPtr;
  68. short     csCode,refNum;
  69. Str255    formatstring;
  70. short     err;
  71. TraceStatusBlk    status;
  72. TraceParamBlock     param;
  73. char len, x;
  74. char *help0 = "\pTo be used with Tracks";
  75. char *help1 = "\pSyntax Error";
  76. char *help2 = "\pFormat: Tracks On .DrvrName | Off | Write | Info";
  77. char drvrName[255];
  78.  
  79.     switch (paramPtr->request)
  80.         {
  81.         case dcmdInit:
  82.             break;
  83.  
  84.         case dcmdHelp:
  85.             dcmdDrawLine (help0);
  86.             dcmdDrawLine (help2);
  87.             break;
  88.  
  89.         case dcmdDoIt:
  90.         {
  91.         
  92.             dcmdSwapWorlds();            // We access machine state. (i think)
  93.  
  94.             (void)dcmdGetNextParameter(formatstring);
  95.             // get the length byte and convert to uppercase
  96.             len = *formatstring;
  97.             for (x=1;x<len+1;x++)
  98.                 if (formatstring[x] <= 'z' && formatstring[x] >= 'a')
  99.                     formatstring[x] -= ('a'-'A');
  100.             PutPStr("\pTracks ");
  101.             
  102.             PutLine();
  103.             PutPStr(formatstring);
  104.             PutLine();
  105.             
  106.             csParamPtr = nil;
  107.             csCode = -1;
  108.             
  109.             // compare command with the pascal strings...
  110.             if (EqlStr("ON", (char *)&formatstring[1])) 
  111.             {
  112.                 (void)dcmdGetNextParameter(formatstring);
  113.                 if (formatstring[1] == '.') 
  114.                 {
  115.                 // it appears that TMON treats a period before a word as a separate word...
  116.                 // so I check for a single word consisting of a period here..
  117.                     if (formatstring[0] == 1)
  118.                     {                        
  119.                         // Must be using TMON...  Grab the next word, and stuff
  120.                         // driver name into drvrName and put in period & new length byte.
  121.                         
  122.                         (void)dcmdGetNextParameter(formatstring);
  123.                         len = *formatstring;
  124.                         for (x=0;x<len+1;x++)
  125.                             drvrName[x+2] = formatstring[x+1];
  126.                         drvrName[0] = len+1;
  127.                         drvrName[1] = '.';
  128.                     } else
  129.                     {
  130.                         len = *formatstring;
  131.                         for (x=0;x<len+1;x++)
  132.                             drvrName[x] = formatstring[x];
  133.                     }
  134.                 // the next parameter needs to be the name of the driver to be traced
  135.                 // it'll return error if not there or the wrong name is specified.
  136.                 if (*drvrName != 0)
  137.                 {
  138.                     PutCStr("opening '");
  139.                     PutPStr(drvrName);
  140.                     PutCStr("'");
  141.                     PutLine();
  142.                     csCode = kSetTraceOnline;
  143.                     csParamPtr = (Ptr)drvrName;    
  144.                 }
  145.  
  146.                 } else PutCStr("missing period");
  147.             }
  148.             else
  149.             if (EqlStr("OFF", (char *)&formatstring[1])) 
  150.                 {
  151.                     csCode = kSetTraceOffline;
  152.                 }
  153.             else
  154.             if (EqlStr("WRITE", (char *)&formatstring[1])) 
  155.                 {
  156.                     csCode = kWriteTraceBuffer;
  157.                 }
  158.             else
  159.             if (EqlStr("INFO", (char *)&formatstring[1]) || (*formatstring == 0)) 
  160.                 {
  161.                     param.u.getStatus.statusPtr = &status;
  162.                     csCode = kGetTraceStatus;
  163.                     csParamPtr = (Ptr) ¶m;
  164.                 }
  165.             
  166.             if (csCode != -1)
  167.             {
  168.                 // err = OpenDriver ("\p.TRACE", &refNum);
  169.                 // the following line is better than using OpenDriver since it doesnt move mem.
  170.  
  171.                 refNum = GetDrvrRefNum((char *)"\p.TRACE");
  172.                 
  173.                 
  174.                 if (refNum != 0)
  175.                     err = Control(refNum, csCode, csParamPtr);
  176.                 else
  177.                 {
  178.                     err = dInstErr;
  179.                     PutCStr("Couldnt open Tracks.");
  180.                 }
  181.  
  182.                 if ((err == noErr) && (csCode == kGetTraceStatus))
  183.                 {
  184.                     PutCStr(" Tracks :");
  185.                     if (status.online) PutCStr(" On");
  186.                     else PutCStr(" Off");
  187.                     PutLine();
  188.                         
  189.                     PutCStr(" Periodic write to file:");
  190.                     if (status.autoWrite) PutCStr(" On");else PutCStr(" Off");
  191.                     PutLine();
  192.                     
  193.                     
  194.                     PutCStr(" bufferSize:      "); 
  195.                     PutUDec(status.bufferSize);
  196.                     if (status.bufferSize == 0) PutCStr(" (Tracks not available)");
  197.                     PutLine();
  198.                     
  199.                     PutCStr(" bytesBuffered:   "); PutUDec(status.bytesBuffered);PutLine();
  200.                     PutCStr(" File Length:     "); PutUDec(status.bytesWritten);PutLine();
  201.                     dcmdDrawLine (help2);
  202.                 }
  203.                 else 
  204.                 {
  205.                 PutCStr("Result: ");
  206.                 PutSignedWord(err);
  207.                 if (err == aspBufTooSmall) PutCStr("(Buffer too small)");
  208.                 PutLine();
  209.                 }
  210.             } 
  211.             else // no match of parameter...
  212.             {    
  213.                 dcmdDrawLine (help0);
  214.                 dcmdDrawLine (help2);
  215.             }
  216.             dcmdSwapWorlds();        // undo
  217.         }
  218.             break;
  219.         }
  220. } // CommandEntry
  221.  
  222.  
  223. // displays a signed value using Put's unsigned short printer.
  224. void PutSignedWord(short err)
  225. {
  226.     if (err & 0x8000)     // it's negitive
  227.     {    
  228.         err = 0xFFFF - err;
  229.         err++;    
  230.         PutChar('-');
  231.     }
  232.     PutUDec((long)err);
  233. }
  234.  
  235. Boolean EqlStr(const char *a, const char *b)
  236. {
  237.     while (*a) 
  238.         if (*a++ != *b++) return false;
  239.     return true;
  240. }
  241. // This was taken from tech note 171
  242. // (modified slightly)
  243. short GetDrvrRefNum(char *driverName)
  244. {  /* GetDrvrRefNum */
  245.  
  246.     #define        UnitNtryCnt    0x1d2
  247.  
  248.     /*bit in dCtlFlags that indicates ROM/RAM*/
  249.     #define          dRAMBased     6        
  250.     /*length byte and name of driver [string]*/
  251.     #define          drvrName      0x12      
  252.  
  253.     short            negCount,dRef;
  254.     DCtlHandle        DCEH;
  255.     char            *drivePtr,*s;
  256.     Boolean found;
  257.  
  258.     negCount = -*(short *)(UnitNtryCnt); /*get -(table size)*/
  259.         
  260.     /*Check to see that driver is installed, obtain refNum.*/
  261.     /*Assumes that an Open was done previously -- probably by an INIT.*/
  262.     /*Driver doesn't have to be open now, though.*/
  263.         
  264.     
  265.     dRef = -12 + 1;  /*we'll start with driver refnum == -12,
  266.              right after .ATP entry*/
  267.  
  268.     /*Look through unit table until we find the driver or reach the     end.*/
  269.         
  270.     do
  271.     {
  272.         dRef -= 1; /*bump to next refnum*/
  273.         DCEH = GetDCtlEntry(dRef); /*get handle to DCE*/
  274.             
  275.         s = "";
  276.  
  277.         if ((DCEH != nil) && ( (**DCEH).dCtlDriver != nil) )
  278.         {
  279.             if (((**DCEH).dCtlFlags >> dRAMBased) & 1)
  280.                                 /* test dRamBased bit */
  281.                 drivePtr = *(Handle) (**DCEH).dCtlDriver;
  282.                                 /*zee deréference*/
  283.             else
  284.                 drivePtr = (**DCEH).dCtlDriver;
  285.             
  286.             if (drivePtr != nil)  
  287.                 s = drivePtr + drvrName;
  288.         }
  289.         
  290.         found = EqualString(s,driverName,0,0);
  291.  
  292.     
  293.     } while (!found && (dRef != negCount));
  294.     /*Loop until we find it or we've just looked at the last slot.*/
  295.  
  296.     return found ? dRef : 0;        // if found return dRef, else 0        
  297.  
  298. }/* GetDrvrRefNum */
  299.  
  300.  
  301. // This is so we don't have to include StdCLib.o -
  302. size_t strlen (const char *s)
  303. {
  304. register size_t size = 0;
  305.     while (*s++) size++;
  306.     return size;
  307.  
  308. }
  309.